#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of_gpio.h>
#include <linux/semaphore.h>
#include <linux/timer.h>
#include <linux/irq.h>
#include <linux/wait.h>
#include <linux/poll.h>
#include <linux/fs.h> 
#include <linux/fcntl.h>
#include <linux/platform_device.h>
#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/i2c.h>

#define DEV_NAME "MyAp3216c"
#define DEV_NUM  1

struct ap3216c_dev_t
{
    char *name;                     //设备名
    int num;                    //设备数量
    dev_t ap3216c_devid;                //ap3216c设备号
    struct cdev ap3216c_cdev;	        //cdev结构体	    
	struct class *ap3216c_class;	    //ap3216c类
	struct device *ap3216c_device;	    //ap3216c设备
    struct file_operations fops;     //操作函数
    struct i2c_client *client;          //iic设备
};

struct ap3216c_dev_t ap3216c_dev;

/* 设备操作函数 */
// static struct file_operations key_fops = {
// 	.owner = THIS_MODULE,
// 	.open = key_open,
// 	.write = key_write,
//     .read = key_read,
// };

static int ap3216c_open(struct inode *inode, struct file *filp)
{
    return 0;
}
static ssize_t ap3216c_read(struct file *filp, char __user *buf, size_t cnt, loff_t *off)
{
    return 0;
}
static int ap3216c_release(struct inode *inode, struct file *filp)
{
    return 0;
}
static int ap3216c_probe(struct i2c_client *client,const struct i2c_device_id *device_id)
{
    /*
    .定义操作函数
    .定义设备结构体
    .申请设备号
    .绑定字符设备和操作函数
    .绑定字符设备和设备号
    .创建类,设备
    */

    //填充fops结构体
    ap3216c_dev.fops.owner = THIS_MODULE;
    ap3216c_dev.fops.open = ap3216c_open;
    ap3216c_dev.fops.read = ap3216c_read;
    ap3216c_dev.fops.release = ap3216c_release;

    //申请设备号
    ap3216c_dev.name = DEV_NAME;
    ap3216c_dev.num = DEV_NUM;
    alloc_chrdev_region(&ap3216c_dev.ap3216c_devid,0,ap3216c_dev.num,ap3216c_dev.name);

    //绑定cdev结构体和文件操作集合
    ap3216c_dev.ap3216c_cdev.owner = THIS_MODULE;
    cdev_init(&ap3216c_dev.ap3216c_cdev,&ap3216c_dev.fops);

    //绑定cdev结构体和设备号
    cdev_add(&ap3216c_dev.ap3216c_cdev,ap3216c_dev.ap3216c_devid,ap3216c_dev.num);

    //创建类和设备
    ap3216c_dev.ap3216c_class = class_create(THIS_MODULE,ap3216c_dev.name);        //创建类
    ap3216c_dev.ap3216c_device = device_create(ap3216c_dev.ap3216c_class, NULL, ap3216c_dev.ap3216c_devid, NULL, ap3216c_dev.name);//创建设备

    printk("Adder:%02x\r\n",client->addr);
    return 0;
}
static int ap3216c_remove(struct i2c_client *client)
{
    return 0;
}
/* 传统匹配方式ID列表 */
static const struct i2c_device_id ap3216c_id[] = {
	{"alientek,ap3216c", 0},  
	{}
};
static struct of_device_id IIC_of_match[] = 
{
    {.compatible = "MyAp3216cDriver"},
    { /* Sentinel */ }
};
static struct i2c_driver ap3216c_driver = {
    .driver		= {
        .owner = THIS_MODULE,
		.name	= "MyAp3216cDriver111",			/* 驱动名字，用于和设备匹配 */
		.of_match_table	= IIC_of_match,     /* 设备树匹配表，用于和设备匹配*/
	},
    .id_table = ap3216c_id,
	.probe		= ap3216c_probe,
	.remove		= ap3216c_remove,
};
static int __init ap3216c_Init(void)
{
    int ret = 0;
    printk("Begin Init...\r\n");
	ret = i2c_add_driver(&ap3216c_driver);
    // printk("ret:%d\r\n",ret);
	return ret;
}
static void __exit ap3216c_Exit(void)
{
    i2c_del_driver(&ap3216c_driver);
}

module_init(ap3216c_Init);
module_exit(ap3216c_Exit);
MODULE_AUTHOR("ZiXie");
MODULE_LICENSE("GPL");